#!/usr/bin/python


import pygame
import MoveableEntity
import EntityObserver
import game_engine.GameEngine
import math


# Class defining a monster that follows the player around and is pretty annoying
class FollowMonster(MoveableEntity.MoveableEntity, EntityObserver.EntityObserver):

    # Obvious
    def __init__(self, name):
        super(FollowMonster, self).__init__(name)
        self.m_following=None
        self.m_lastAgroCheck=0
        self.m_needPathUpdate = False
        self.m_lastAttack=0
        self.setAttackDamage(1)


    
    def frameUpdate(self, elapsedms, absolutems):
        # Check for aggro
        if self.m_lastAgroCheck + 1000 <= absolutems:
            self.checkAgro()
            self.m_lastAgroCheck = absolutems

        # Update follow if needed
        if not(self.m_following is None) and self.m_needPathUpdate:
            pathFinder = game_engine.GameEngine.getGameEngine().getPathFinder()
            ignoreList = [ self.m_following ] 
            path = pathFinder.findPathToClosestReachable(self, self.m_following.getPosition(), ignoreList)
            #print "Path:", path
            if len(path) == 0:
                print "Cant reach player. Stopping follow."
                self.stopFollowing()
            else:
                self.tryFollowPath(path, 500)
            self.m_needPathUpdate = False

        # If we're adjacent to the target, stop walking our path and attack!
        if not(self.m_following is None):
            if self.isAdjacentTo(self.m_following):
                self.stopPath()
                if self.m_lastAttack + 1000 <= absolutems:
                    # Attack for 1 damage
                    self.m_following.interactAttacked(self)
                    self.m_lastAttack = absolutems


        # Call base class
        super(FollowMonster, self).frameUpdate(elapsedms, absolutems)


    # Check whether we should engage player
    def checkAgro(self):
        # Hack - aggro distance
        playerEntity = game_engine.GameEngine.getGameEngine().getEntityManager().getPlayerEntity()
        (playerX, playerY) = playerEntity.getPosition()
        #print "my X:" + str(self.m_positionX)+" Y:"+str(self.m_positionY)
        #print "player X:" + str(playerX)+" Y:"+str(playerY)

        distance = math.sqrt(((self.m_positionX - playerX) ** 2) + ((self.m_positionY - playerY) ** 2)) 

        if distance < 16 and playerEntity.isAlive(): 
            if self.m_following is None:
                print "Following player."
                # Track our followed player
                self.m_following=playerEntity
                # Observe followed player
                playerEntity.addObserver(self)
                # Need a path update
                self.m_needPathUpdate = True
            
        else:
            if not(self.m_following is None):
                self.stopFollowing()


    # Entity destroyed
    def observeEntityDestroyed(self, entity):
        # Don't need to follow anymore
        print "Player destroyed. Not following."
        self.stopFollowing()

    # Entity moved
    def observeEntityMoved(self, entity, (oldx, oldy)):
        # If we're not following this entity anymore, ignore
        if self.m_following is None:
            return
        # Otherwise note that we need to update our path next frame
        self.m_needPathUpdate = True

    # Entity killed
    def observeEntityKilled(self, entity, killedByEntity = None):
        print "Player killed. Not following."
        self.stopFollowing()

    # Common logic to stop following target
    def stopFollowing(self):
        if self.m_following is None:
            return
        print "Stopped following player."
        # Stop observing
        self.m_following.removeObserver(self)
        # Remove following reference
        self.m_following = None
        # Stop walking the path
        self.stopPath()
        

